import { App, watch, reactive } from 'vue'
import { bind as bindUpdateProps, unbind as unBindUpdateProps } from './updateProps'
import BUS_EVENT_KEYS from './constants/BUS_EVENT_KEYS'
import parentDataMsgHandle from '../parentDataMsgHandle'
import {
    _subscriptTrigger,
    _onMicroActivatedHandlers,
    _onMicroDeactivatedHandlers,
    _onMicroInitializedHandlers
} from '../lifecycle'

interface Params {
    /**
     * 首次挂载会触发，销毁后再挂载会触发
     * @returns
     */
    onInitialized?: () => void
    /**
     * 激活触发
     * @returns
     */
    onActivated?: () => void
    /**
     * 失活触发
     * @returns
     */
    onDeactivated?: () => void
}

export default (init?: Params) => {
    /**
     * 在应用首次加载时（window 初次创建），初始化一个标志位
     * 以标志位判断是否是首次加载，保活模式下，不会触发这个
     */
    window['__INITIALIZED__'] = undefined

    /**
     * 只有基座下的直接子应用采用采用保活模式，保活模式触发 activated & deactivated 生命周期
     * 在 激活 & 失活 两种情况下，进行 数据/变化 的绑定 & 解绑
     * 详见：https://wujie-micro.github.io/doc/guide/mode.html#%E8%BF%90%E8%A1%8C%E6%A8%A1%E5%BC%8F
     */
    window[BUS_EVENT_KEYS.MICRO_ACTIVATED] = function () {
        // 基座数据变化绑定
        bindUpdateProps()

        // 激活
        init?.onActivated?.()
        _subscriptTrigger(_onMicroActivatedHandlers)

        // 初始化
        if (!window['__INITIALIZED__']) {
            init?.onInitialized?.()
            _subscriptTrigger(_onMicroInitializedHandlers)
        }
        window['__INITIALIZED__'] = true
    }

    window[BUS_EVENT_KEYS.MICRO_DEACTIVATED] = function () {
        // 基座数据变化解绑
        unBindUpdateProps()

        // 失活
        init?.onDeactivated?.()
        _subscriptTrigger(_onMicroDeactivatedHandlers)
    }

    /**
     * 运行在远程组件容器中，没有 activated & deactivated 生命周期
     */
    if (window.__IS_REMOTE_COMPONENT__ && window.$wujie?.props) {
        /**
         * 微应用启动数据广播
         */
        window.$wujie?.bus.$on(
            BUS_EVENT_KEYS.REMOTE_COMPONENT_VIEW_UPDATE_PROPS,
            parentDataMsgHandle
        )
        parentDataMsgHandle(window.$wujie?.props)

        /**
         * TODO: 远程组件容器微应用加载完毕模拟
         * 无界微应用在没有改造生命周期的情况下，是没有标识 mounted 的生命周期的
         * 这里只是做一个假的挂载完毕的通知
         * 一般情况下，远程组件容器采用重建模式，重建模式会重新执行微应用的 js
         * 一般来说，执行到这一步时微应用主程序（耗费时间）的 js 都已执行完毕，后续虽然还会有执行（app 实例挂载）可以忽略
         * 另放到了异步队列中，尽可能的模拟到微应用挂载完成事件
         */
        if (window.$wujie?.props?.childrenLoaded) {
            setTimeout(() => {
                window.$wujie?.props?.childrenLoaded(true)
            }, 0)
        }
    }
}
